package com.weishaoying.mongo.dao;

import com.mongodb.BasicDBObject;
import com.mongodb.WriteResult;
import com.weishaoying.mongo.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author WeiShaoying
 * @date 2018/5/16
 * <p>
 * https://blog.csdn.net/lxb15959168136/article/details/52253415
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void saveUser(UserEntity user) {
        mongoTemplate.save(user);
    }

    @Override
    public UserEntity queryUserByUserName(String userName) {
        Query query = new Query(Criteria.where("userName").is(userName));
        UserEntity userEntity = mongoTemplate.findOne(query, UserEntity.class);
        return userEntity;
    }

    @Override
    public int updateUser(UserEntity user) {
        Query query = new Query(Criteria.where("id").is(user.getId()));
        Update update = new Update()
                .set("userName", user.getUserName())
                .set("passWord", user.getPassWord());
        //更新符合条件的第一个
        WriteResult result = mongoTemplate.updateFirst(query, update, UserEntity.class);
        if (result != null) {
            return result.getN();
        }
        return 0;
    }

    @Override
    public int batchUpdate(List<Long> idList, String username) {
        Query query = new Query(Criteria.where("id").in(idList));
        Update update = new Update().set("userName", username);
        //更新查询出来的所有
        WriteResult result = mongoTemplate.updateMulti(query, update, UserEntity.class);
        if (null != result) {
            return result.getN();
        }
        return 0;
    }

    @Override
    public void deleteUserById(Long id) {
        Query query = new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, UserEntity.class);
    }

    @Override
    public List<UserEntity> pageQuery(String name, int pageSize, int pageNo) {
        Query query = new Query();

        //Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
        //query.addCriteria(Criteria.where("userName").regex(pattern));
        query.addCriteria(Criteria.where("userName").regex(".*" + name + ".*"));
        //时间比较
        //Criteria criteria = Criteria.where("timeDate").gte(timeDateStart).lt(timeDateEnd);
        //按照id升序
        Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));
        //分页查询
        return mongoTemplate.find(query.with(sort).limit(pageSize).skip((pageNo - 1) * pageSize), UserEntity.class);
    }

    @Override
    public List<UserEntity> queryNameNotEmpty() {
        Query query = new Query();
        Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "id"));
        query.addCriteria(Criteria.where("name").ne("").ne(null));
        return mongoTemplate.find(query.with(sort), UserEntity.class);
    }

    @Override
    public List<UserEntity> queryByAge(int age1, int age2, int age3) {
        Query query = new Query();
        query.addCriteria(new Criteria().orOperator(
                Criteria.where("age").is(age1),//这里是可变参数
                Criteria.where("age").is(age2),
                Criteria.where("age").is(age3)
        ));
        return mongoTemplate.find(query, UserEntity.class);
    }

    @Override
    public List<UserEntity> queryByNameAndAge(String name, Integer age) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and("name").regex(".*" + name + ".*");
        criteria.and("age").gte(age);
        query.addCriteria(criteria);
        long count = mongoTemplate.count(query, UserEntity.class);
        System.out.println(age + "岁以上的人name like " + name + ",人数=" + count);

        return mongoTemplate.find(query, UserEntity.class);
    }


    //MongoDB mongoTemplate查询条作组合例子 - - ITeye博客  http://huangyongxing310.iteye.com/blog/2342307
    public void findtest() {
        TypedAggregation<UserEntity> agg = Aggregation.newAggregation(UserEntity.class,
                Aggregation.group("onlineStatus").count().as("num"),
                Aggregation.project("num").and("onlineStatus").previousOperation()// 结果包含那些字段（num）,挑选所需的字段，用"onlineStatus"显示分组的类型，并且不输出以“_id”分组的结果
        );

        System.out.println(" agg == " + agg.toString());
        // { "aggregate" : "__collection__" , "pipeline" : [ { "$group" : {"_id" : "$onlineStatus" , "num" : { "$sum" : 1}}} , { "$project" : {"num" : 1 , "_id" : 0 , "onlineStatus" : "$_id"}}]}
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(agg, BasicDBObject.class);
        // [{ "num" : 3 , "onlineStatus" : "1"}, { "num" : 3 , "onlineStatus" :"0"}]


        result.getMappedResults();

        System.out.println(" result.getMappedResults == " + result.getMappedResults().toString());
        List list = new ArrayList<>();

    }

}
